Imports System.IO

Friend Class TH_BikiRom_Down
    Friend m_start As Integer = 0
    Friend m_end As Integer = 262143
    Friend m_packetSize As Integer = 256
    Friend m_action As BikiAction = BikiAction.BK_NONE

    Private m_progress As Integer
    Private m_message As String
    Private m_data() As Byte
    Private m_eepromData() As Byte

    Friend Event Progress(ByVal sender As Object, ByVal e As TH_BikiRom_DownArgs)
    Friend Event Message(ByVal sender As Object, ByVal e As TH_BikiRom_DownArgs)
    Friend Event getArray(ByVal sener As Object, ByVal e As TH_BikiRom_DownArgs)

    Private bgw As System.ComponentModel.BackgroundWorker
    Private eventArgs As System.ComponentModel.DoWorkEventArgs

    Friend Sub New(ByVal packetSize As Integer, ByVal Action As BikiAction)
        m_packetSize = packetSize
        m_action = Action
        'ReDim m_data(0 To m_end - m_start)
    End Sub

    Friend Function Execute( _
         ByVal backGroundWorker As System.ComponentModel.BackgroundWorker, _
         ByVal e As System.ComponentModel.DoWorkEventArgs) As Boolean

        ' Store the reference to the BackgroundWorker and the
        ' DoWorkEventArgs objects:
        bgw = backGroundWorker
        eventArgs = e

        ' Search for matching files.

        Dim f_Array(&H40CFF) As Byte
        Dim f_offset As Integer = 0

        Dim f_return As BK_return = BikiRom_Init()
        If f_return <> BK_return.BK_OK Then GoTo endE

        m_BikiInfo.TimeOut = 500

        OnMessage("Downloading.........")
        If m_action = BikiAction.BK_ALL Then
            f_return = downloadNew(BikiAction.BK_ALL, f_Array, f_offset)
            If f_return <> BK_return.BK_OK Then GoTo endE
            f_return = downloadNew(BikiAction.BK_EEPROM, f_Array, f_offset)
            If f_return <> BK_return.BK_OK Then GoTo endE
            OnMessage("Downloading Complete")
        Else
            ReDim f_Array(&H40CFF)
            If Not m_action And BikiAction.BK_MAP1 Then ReDim Preserve f_Array(UBound(f_Array) - &H10000)
            If Not m_action And BikiAction.BK_MAP2 Then ReDim Preserve f_Array(UBound(f_Array) - &H10000)
            If Not m_action And BikiAction.BK_MAP3 Then ReDim Preserve f_Array(UBound(f_Array) - &H10000)
            If Not m_action And BikiAction.BK_CFG Then ReDim Preserve f_Array(UBound(f_Array) - &H10000)
            If Not m_action And BikiAction.BK_EEPROM Then ReDim Preserve f_Array(UBound(f_Array) - &HCFF)

            If m_action And BikiAction.BK_MAP1 Then
                f_return = downloadNew(BikiAction.BK_MAP1, f_Array, f_offset)
                If f_return <> BK_return.BK_OK Then GoTo endE
                ' f_offset += &H10000
            End If

            If m_action And BikiAction.BK_MAP2 Then
                f_return = BikiRom_Init()
                If f_return <> BK_return.BK_OK Then GoTo endE
                f_return = downloadNew(BikiAction.BK_MAP2, f_Array, f_offset)
                If f_return <> BK_return.BK_OK Then GoTo endE
                ' f_offset += &H10000
            End If

            If m_action And BikiAction.BK_MAP3 Then
                f_return = BikiRom_Init()
                If f_return <> BK_return.BK_OK Then GoTo endE
                f_return = downloadNew(BikiAction.BK_MAP3, f_Array, f_offset)
                If f_return <> BK_return.BK_OK Then GoTo endE
                ' f_offset += &H10000
            End If

            If m_action And BikiAction.BK_CFG Then
                f_return = BikiRom_Init()
                If f_return <> BK_return.BK_OK Then GoTo endE
                f_return = downloadNew(BikiAction.BK_CFG, f_Array, f_offset)
                If f_return <> BK_return.BK_OK Then GoTo endE
                ' f_offset += &H10000
            End If

            If m_action And BikiAction.BK_EEPROM Then
                f_return = BikiRom_Init()
                If f_return <> BK_return.BK_OK Then GoTo endE
                f_return = downloadNew(BikiAction.BK_EEPROM, f_Array, f_offset)
                If f_return <> BK_return.BK_OK Then GoTo endE
                ' f_offset += &HCFF
            End If

            OnMessage("Downloading Complete")
        End If

        m_data = f_Array
        onArray(m_data)
        Close_BikiRom()
        Return True
        Exit Function
endE:
        OnMessage(Err_Decode(f_return))
        Return False
    End Function

    Protected Sub onArray(ByRef Array() As Byte)
        RaiseEvent getArray(Me, New TH_BikiRom_DownArgs(m_progress, m_message, m_data))
    End Sub
    Protected Sub OnProgress(ByVal progress As Integer)
        ' A file was found. Increment the counter,
        ' then raise the event indicating that the file was found.
        ' Note that RaiseEvent is synchronous: You're not
        ' going any further until the event is handled by all
        ' listeners.
        m_progress = progress
        RaiseEvent Progress(Me, New TH_BikiRom_DownArgs(m_progress, m_message))
    End Sub

    Protected Sub OnMessage(ByVal Message As String)
        ' A file was found. Increment the counter,
        ' then raise the event indicating that the file was found.
        ' Note that RaiseEvent is synchronous: You're not
        ' going any further until the event is handled by all
        ' listeners.
        m_message = Message
        RaiseEvent Message(Me, New TH_BikiRom_DownArgs(m_progress, m_message))
    End Sub

    '    Private Function download(ByVal Action As BikiAction, ByRef retArray() As Byte, ByVal Offset As Integer) As BK_return
    '        Dim m_loop As Integer
    '        Dim s_cmd() As Byte = Nothing
    '        Dim a_cmd() As Byte = Nothing
    '        Dim m_ret(m_packetSize + 2) As Byte
    '        Dim e As Short
    '        'ReDim m_ret(m_packetSize + 2)

    '        If bgw.CancellationPending Then
    '            eventArgs.Cancel = True
    '            Return BK_return.BK_TH_CANCELLED
    '        End If

    '        Select Case Action
    '            Case BikiAction.BK_MAP1
    '                s_cmd = cv_BytesFromHex("CC3200")
    '                a_cmd = cv_BytesFromHex("AF0000")
    '                m_start = 0
    '                m_end = 65535
    '            Case BikiAction.BK_MAP2
    '                s_cmd = cv_BytesFromHex("CC3200")
    '                a_cmd = cv_BytesFromHex("AF8000")
    '                m_start = 0
    '                m_end = 65535
    '            Case BikiAction.BK_MAP3
    '                s_cmd = cv_BytesFromHex("CC3201")
    '                a_cmd = cv_BytesFromHex("AF0000")
    '                m_start = 0
    '                m_end = 65535
    '            Case BikiAction.BK_CFG
    '                s_cmd = cv_BytesFromHex("CC3201")
    '                a_cmd = cv_BytesFromHex("AF8000")
    '                m_start = 0
    '                m_end = 65535
    '            Case BikiAction.BK_ALL
    '                s_cmd = cv_BytesFromHex("CC3200")
    '                a_cmd = cv_BytesFromHex("AF0000")
    '                m_start = 0
    '                m_end = 262143
    '        End Select

    '        ' FT_Purge lngHandle, FT_PURGE_RX + FT_PURGE_TX
    '        's_cmd = cv_BytesFromHex("CC3200")
    '        If Not BikiRom_sendCmdd(s_cmd, m_ret, 3, 1) Then
    '            Return BK_return.BK_IO_ERROR_BIK
    '        Else
    '            If Not m_ret(0) = 170 Then
    '                Return BK_return.BK_FAILED_CMD
    '            End If
    '        End If

    '        If Not BikiRom_sendCmdd(a_cmd, m_ret, 3, 1) Then
    '            Return BK_return.BK_IO_ERROR_BIK
    '        Else
    '            If Not m_ret(0) = 170 Then
    '                Return BK_return.BK_FAILED_CMD
    '            End If
    '        End If

    '        System.Threading.Thread.Sleep(20)
    '        Dim s_crc As Int64
    '        Dim s_error As Integer


    '        For m_loop = m_start To m_end Step m_packetSize
    '            s_cmd = cv_BytesFromHex("DF")
    'repeat:
    '            If Not BikiRom_sendCmdd(s_cmd, m_ret, 1, m_packetSize + 2) Then
    '                s_error += 1
    '                If s_error > 100 Then Return BK_return.BK_IO_ERROR_BIK
    '                s_cmd = cv_BytesFromHex("EE")
    '                GoTo repeat
    '            End If

    '            s_crc = 0
    '            For e = 1 To m_packetSize : s_crc += m_ret(e) : Next

    '            If LOBYTE(s_crc) <> m_ret(m_packetSize + 1) Then
    '                s_error += 1
    '                If s_error > 100 Then Return BK_return.BK_IO_CRC_FAILED
    '                s_cmd = cv_BytesFromHex("EE")
    '                GoTo repeat
    '            Else : For e = 1 To m_packetSize : retArray(m_loop + e - 1 + Offset) = m_ret(e) : Next
    '            End If

    '            If bgw.CancellationPending Then
    '                eventArgs.Cancel = True
    '                Return BK_return.BK_TH_CANCELLED
    '            End If

    '            If m_loop Mod 1024 = 0 Then
    '                OnProgress(((m_loop - m_start + Offset) / (UBound(retArray) - m_start)) * 100)
    '            End If
    '        Next
    '        If Not BikiRom_hexCmd("FF") Then
    '            Return BK_return.BK_IO_ERROR_USB
    '        Else
    '            Return BK_return.BK_OK
    '        End If
    '    End Function

    Private Function downloadNew(ByVal Action As BikiAction, ByRef retArray() As Byte, ByRef Offset As Integer) As BK_return
        Dim i As ULong
        Dim f_Frame As Comm.Comm_Frame = Nothing
        Dim f_PacketSize As UInt16 = m_BikiInfo.MaxRxPacket
        Dim f_FakePacket(f_PacketSize - 1) As Byte
        Dim f_ReturnPacket() As Byte = Nothing
        Dim f_Return As Comm.Comm_Frame.BikiFrameResponse = Comm.Comm_Frame.BikiFrameResponse.CMD_OK
        Dim f_returnExcp As Comm_Exceptions
        Dim f_FrameAction As Comm.Comm_Frame.BikiFrameType = Comm.Comm_Frame.BikiFrameType.ID_FLASH_DATA

        If bgw.CancellationPending Then
            eventArgs.Cancel = True
            Return BK_return.BK_TH_CANCELLED
        End If

        Select Case Action
            Case BikiAction.BK_MAP1
                m_start = 0
                m_end = 65535
            Case BikiAction.BK_MAP2
                m_start = 65536
                m_end = 131071
            Case BikiAction.BK_MAP3
                m_start = 131072
                m_end = 196607
            Case BikiAction.BK_CFG
                m_start = 196608
                m_end = 262143
            Case BikiAction.BK_ALL
                m_start = 0
                m_end = 262143
            Case BikiAction.BK_EEPROM
                m_start = 0
                m_end = &HCFF
                f_FrameAction = Comm.Comm_Frame.BikiFrameType.ID_EEPROM_DATA
        End Select
        Try
            For i = m_start To m_end - f_PacketSize Step f_PacketSize
                ' get each and every packet
                f_Frame = New Comm.Comm_Frame(f_FrameAction, i, Comm.Comm_Frame.BikiFrameAction.READ, f_FakePacket, f_FrameAction)

                f_Return = f_Frame.Send(f_ReturnPacket, , 30)

                f_returnExcp = New Comm_Exceptions(f_Return)

                Array.Copy(f_ReturnPacket, 5, retArray, CLng(Offset + (i - m_start)), f_PacketSize)

                OnProgress(((i - m_start + Offset) / (UBound(retArray) - m_start)) * 100)
            Next

            If ((m_end - m_start) Mod f_PacketSize) <> 0 Then
                ' get the final and last packet here... fool :)
                f_PacketSize = (m_end Mod f_PacketSize) + 1
                ReDim f_FakePacket(f_PacketSize - 1)

                f_Frame = New Comm.Comm_Frame(f_FrameAction, m_end - f_PacketSize + 1, Comm.Comm_Frame.BikiFrameAction.READ, f_FakePacket, f_FrameAction)
                f_Return = f_Frame.Send(f_ReturnPacket, , 30)

                f_returnExcp = New Comm_Exceptions(f_Return)

                Array.Copy(f_ReturnPacket, 5, retArray, CLng(Offset + (m_end - m_start) - f_PacketSize + 1), f_PacketSize)
            End If

            ' Increment the offset for the passback
            Offset += (m_end - m_start) + 1

        Catch exComm As Comm_Exceptions
            OnMessage(exComm.Description)
            Return BK_return.BK_IO_ERROR_BIK
        Catch exUsb As USB_exceptions
            OnMessage(exUsb.Description)
            Return BK_return.BK_IO_ERROR_USB
        End Try
        Return BK_return.BK_OK
    End Function
End Class
